/**
 * Alibaba.com.cn Inc.
 * Copyright (c) 2004-2021 All Rights Reserved.
 */
package com.smart.helper;

import cn.hutool.core.date.StopWatch;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.smart.common.Constants;
import com.smart.common.enums.DictEnum;
import com.smart.common.enums.ErrorCode;
import com.smart.common.exception.BusinessException;
import com.smart.mapper.ProjectMapper;
import com.smart.mapper.StreetMapper;
import com.smart.model.domain.*;
import com.smart.model.excel.ItemVO;
import com.smart.model.vo.DictItemVO;
import com.smart.model.vo.StreetVO;
import com.smart.service.DictItemService;
import com.smart.service.StreetService;
import com.smart.utils.ZipFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 * @version CommonHelper.java, v 0.1 2023/7/19 20:06 下午 CommonHelper Exp $$
 */
@Slf4j
@Component
public class CommonUtil implements InitializingBean {
    public static List<ProvinceDO> provinceList = Lists.newArrayList();
    public static Map<String, String> provinceMap = Maps.newHashMap();

    public static List<CityDO> cityList = Lists.newArrayList();
    public static Map<String, String> cityMap = Maps.newHashMap();

    public static List<AreaDO> areaList = Lists.newArrayList();
    public static Map<String, String> areaMap = Maps.newHashMap();

    public static List<StreetVO> streetList = Lists.newArrayList();
    public static Map<String, String> streetMap = Maps.newHashMap();

    public static List<DictItemVO> buildStatusList = Lists.newArrayList();
    public static Map<String, String> buildStatusMap = Maps.newHashMap();

    public static List<DictItemVO> buildTypeList = Lists.newArrayList();
    public static Map<String, String> buildTypeMap = Maps.newHashMap();

    @Autowired
    private StreetService streetService;
    @Autowired
    private StreetMapper streetMapper;
    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private ProjectMapper projectMapper;

    /**
     * 构建提报项填报数据值（文本、数字）
     * @param reportDO
     * @param ids
     * @return
     */
    public List<String> buildRow(ProjectReportDO reportDO, List<Long> ids) {
        List<ItemVO> itemVOS = JSON.parseArray(reportDO.getContent(), ItemVO.class);
        if (CollectionUtils.isEmpty(itemVOS)) {
            return null;
        }

        List<String> row = Lists.newArrayList();
        Map<Long, ItemVO> map = itemVOS.stream().collect(Collectors.toMap(ItemVO::getId, Function.identity()));
        for (Long id : ids) {
            ItemVO itemVO = map.get(id);
            if (itemVO != null) {
                row.add(itemVO.getVal());
            }
        }
        return row;
    }

    /**
     * 构建填报项（图片）
     * @param reportDO
     * @param ids
     * @param path
     * @return
     */
    public List<File> buildFiles(ProjectReportDO reportDO, List<Long> ids, String path) {
        List<ItemVO> itemVOS = JSON.parseArray(reportDO.getContent(), ItemVO.class);
        if (CollectionUtils.isEmpty(itemVOS)) {
            return null;
        }
        // 查询项目信息
        String projectName = reportDO.getProjectName();
        String qualityRegistrationNumber = reportDO.getQualityRegistrationNumber();
        if (projectName.length() > 70) {
            projectName = projectName.substring(0, 70);
        }
        String dirProjectPathName = String.format("%s-%s", reportDO.getQualityRegistrationNumber(), projectName);

        List<String> row = Lists.newArrayList();
        Map<Long, ItemVO> map = itemVOS.stream().collect(Collectors.toMap(ItemVO::getId, Function.identity()));

        List<File> files = Lists.newArrayList();
        for (Long id : ids) {
            ItemVO itemVO = map.get(id);
            if (itemVO != null && itemVO.getImageNum() != null) {
                String dirItemPathName = File.separator + itemVO.getName();
                if (path != null) {
                    dirItemPathName = path + File.separator + itemVO.getName();
                }
                if (itemVO.getImageNum() == 1) {
                    // 直接放入文件夹
                    StringBuilder fileNameBuilder = new StringBuilder();
                    if (StringUtils.isNotBlank(qualityRegistrationNumber)) {
                        fileNameBuilder.append(qualityRegistrationNumber).append("-");
                    }
                    fileNameBuilder.append(projectName);

                    String fileName = fileNameBuilder.toString();
                    try {
                        if (fileName.length() > 100) {
                            fileName = fileName.substring(0, 70);
                        }
                        if (fileName.startsWith("-")) {
                            fileName = fileName.substring(1);
                        }

                        fileName = fileName + ".png";
                        if (StringUtils.isNotEmpty(itemVO.getVal())) {
                            File download = ZipFileUtils.download(fileName, dirItemPathName, itemVO.getVal());
                            files.add(download);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("云监管平台-填报项图片下载失败:{}", e.getMessage());
                        throw new BusinessException(ErrorCode.INTER_ERR, "云监管平台-填报项图片下载失败");
                    }
                } else {
                    // 新建文件夹然后在访问序号的图片冲1开始
                    String[] split = itemVO.getVal().split(",");
                    for (int i = 1; i <= split.length; i++) {
                        try {
                            String fileName = String.format("%s.png", i);
                            String filePath = dirItemPathName + File.separator + dirProjectPathName;
                            File download = ZipFileUtils.download(fileName, filePath, split[i - 1]);
                            files.add(download);
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("云监管平台-填报项图片下载失败:{}", e.getMessage());
                            throw new BusinessException(ErrorCode.INTER_ERR, "云监管平台-填报项图片下载失败");
                        }
                    }
                }
                row.add(itemVO.getVal());
            }
        }
        return files;
    }

    /**
     * 构建填报项（图片）
     * @param reportDO
     * @param ids
     * @param path
     * @return
     */
    public List<File> buildFiles2(ProjectReportDO reportDO, List<Long> ids, String path) {
        List<ItemVO> itemVOS = JSON.parseArray(reportDO.getContent(), ItemVO.class);
        if (CollectionUtils.isEmpty(itemVOS)) {
            return null;
        }
        // 查询项目信息
        String projectName = reportDO.getProjectName();
        String qualityRegistrationNumber = reportDO.getQualityRegistrationNumber();
        if (projectName.length() > 70) {
            projectName = projectName.substring(0, 70);
        }
        String dirProjectPathName = String.format("%s-%s", reportDO.getQualityRegistrationNumber(), projectName);
        List<String> row = new CopyOnWriteArrayList<>();
        Map<Long, ItemVO> map = itemVOS.stream().collect(Collectors.toMap(ItemVO::getId, Function.identity()));
        List<File> files = new CopyOnWriteArrayList<>();
        ExecutorService executorService = Executors.newFixedThreadPool(ids.size());
        List<Future<File>> futures = new ArrayList<>();

        for (Long id : ids) {
            String finalProjectName = projectName;
            Future<File> future = executorService.submit(new Callable<File>() {
                @Override
                public File call() throws Exception {
                    ItemVO itemVO = map.get(id);
                    if (itemVO != null && itemVO.getImageNum() != null) {
                        String dirItemPathName = File.separator + itemVO.getName();
                        if (path != null) {
                            dirItemPathName = path + File.separator + itemVO.getName();
                        }
                        if (itemVO.getImageNum() == 1) {
                            // 直接放入文件夹
                            StringBuilder fileNameBuilder = new StringBuilder();
                            if (StringUtils.isNotBlank(qualityRegistrationNumber)) {
                                fileNameBuilder.append(qualityRegistrationNumber).append("-");
                            }
                            fileNameBuilder.append(finalProjectName);
                            String fileName = fileNameBuilder.toString();
                            try {
                                if (fileName.length() > 100) {
                                    fileName = fileName.substring(0, 70);
                                }
                                if (fileName.startsWith("-")) {
                                    fileName = fileName.substring(1);
                                }
                                fileName = fileName + ".png";
                                if (StringUtils.isNotEmpty(itemVO.getVal())) {
                                    File download = ZipFileUtils.download(fileName, dirItemPathName, itemVO.getVal());
                                    row.add(itemVO.getVal());
                                    return download;
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("云监管平台-填报项图片下载失败:{}", e.getMessage());
                                throw new BusinessException(ErrorCode.INTER_ERR, "云监管平台-填报项图片下载失败");
                            }
                        } else {
                            // 新建文件夹然后在访问序号的图片冲1开始
                            String[] split = itemVO.getVal().split(",");
                            for (int i = 1; i <= split.length; i++) {
                                try {
                                    String fileName = String.format("%s.png", i);
                                    String filePath = dirItemPathName + File.separator + dirProjectPathName;
                                    File download = ZipFileUtils.download(fileName, filePath, split[i - 1]);
                                    row.add(itemVO.getVal());
                                    return download;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    log.error("云监管平台-填报项图片下载失败:{}", e.getMessage());
                                    throw new BusinessException(ErrorCode.INTER_ERR, "云监管平台-填报项图片下载失败");
                                }
                            }
                        }
                    }
                    return null;
                }
            });
            futures.add(future);
        }

        for (Future<File> future : futures) {
            try {
                File file = future.get();
                if (file != null) {
                    files.add(file);
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
                log.error("云监管平台-填报项图片下载失败:{}", e.getMessage());
                throw new BusinessException(ErrorCode.INTER_ERR, "云监管平台-填报项图片下载失败");
            }
        }

        executorService.shutdown();
        return files;
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        provinceList = streetMapper.queryAllProvinceList();
        if (CollectionUtils.isNotEmpty(provinceList)) {
            provinceMap = provinceList.stream().collect(Collectors.toMap(ProvinceDO::getCode, ProvinceDO::getName));
        }

        cityList = streetMapper.queryAllCityList();
        if (CollectionUtils.isNotEmpty(provinceList)) {
            cityMap = cityList.stream().collect(Collectors.toMap(CityDO::getCode, CityDO::getName));
        }

        areaList = streetMapper.queryAllAreaList();
        if (CollectionUtils.isNotEmpty(provinceList)) {
            areaMap = areaList.stream().collect(Collectors.toMap(AreaDO::getCode, AreaDO::getName));
        }

        streetList = streetService.queryStreetByAreaCode(Constants.DA_XING_AREA_CODE);
        if (CollectionUtils.isNotEmpty(streetList)) {
            streetMap = streetList.stream().collect(Collectors.toMap(StreetVO::getCode, StreetVO::getName));
        }

        buildStatusList = dictItemService.queryDictItemByDictCode(DictEnum.BUILD_TYPE.getCode());
        if (CollectionUtils.isNotEmpty(buildStatusList)) {
            buildStatusMap = buildStatusList.stream().collect(Collectors.toMap(DictItemVO::getDictItemCode, DictItemVO::getDictItemName));
        }

        buildTypeList = dictItemService.queryDictItemByDictCode(DictEnum.PROJECT_TYPE.getCode());
        if (CollectionUtils.isNotEmpty(streetList)) {
            buildTypeMap = buildTypeList.stream().collect(Collectors.toMap(DictItemVO::getDictItemCode, DictItemVO::getDictItemName));
        }
    }
}
